package com.ruoyi.common;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

/**
 * lhp
 * 2024/8/26
 */
public class SFTPUtil {

    private ChannelSftp sftp;
    private Session session;
    /**
     * @return 读取文件内容返回byte数组
     */
    public static byte[] download(String fileName, String path, String host, int port, String user, String password) {
        Session session = null;
        ChannelSftp channel = null;//ChannelSftp类是JSch实现SFTP核心类
        try {
            JSch jsch = new JSch();
            if (port == 0) {
                session = jsch.getSession(user, host);
            } else {
                session = jsch.getSession(user, host, port);
            }
            session.setPassword(password);
            //禁用StrictHostKeyChecking选项会使连接的安全性低于启用该选项的安全性,
            // 因为它可以让您连接到远程服务器而无需验证其SSH主机密钥.如果启用该选项,
            // 则只能连接到SSH客户端已知密钥的服务器
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect(600000);
            channel = (ChannelSftp) session.openChannel("sftp");
            channel.connect(600000);

            if (!(path == null || path.trim().length() == 0)) {
                channel.cd(path);//进入指定目录
            }
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            channel.get(fileName, outputStream);//文件下载,文件不存在报错 2: No such file
            byte[] arrayOfByte = outputStream.toByteArray();
            return arrayOfByte;
        } catch (SftpException e) {
            if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {//2: No such file
                return  null;
                // file doesn't exist
                //throw new RuntimeException(fileName+"文件不存在");
            } else {
                throw new RuntimeException(e);//这个一定要捕捉异常，不然代码报错，为没有返回值
            }
        } catch (Exception e0) {
            throw new RuntimeException(e0);
        } finally {
            if (channel != null) {
                channel.disconnect();
            }
            if (session != null) {
                session.disconnect();
            }
        }
    }


    /**
     * ChannelSftp获取某目录下所有文件名称
     */
    public static List<String> getFileName(String path, String host, int port, String user, String password) {
        Session session = null;
        ChannelSftp channel = null;//ChannelSftp类是JSch实现SFTP核心类
        List<String> fileNameList=new ArrayList<String>();
        try {
            JSch jsch = new JSch();
            if (port == 0) {
                session = jsch.getSession(user, host);
            } else {
                session = jsch.getSession(user, host, port);
            }
            session.setPassword(password);
            //禁用StrictHostKeyChecking选项会使连接的安全性低于启用该选项的安全性,
            // 因为它可以让您连接到远程服务器而无需验证其SSH主机密钥.如果启用该选项,
            // 则只能连接到SSH客户端已知密钥的服务器
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect(600000);
            channel = (ChannelSftp) session.openChannel("sftp");
            channel.connect(600000);

            //ls命令获取文件名列表

            Vector vector = channel.ls(path);
            Iterator iterator = vector.iterator();
            while (iterator.hasNext()) {
                ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) iterator.next();
                fileNameList.add(file.getFilename());
            }
        }catch (SftpException e) {
            if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {//2: No such file
                return  null;
                // file doesn't exist
                //throw new RuntimeException(fileName+"文件不存在");
            } else {
                throw new RuntimeException(e);//这个一定要捕捉异常，不然代码报错，为没有返回值
            }
        } catch (Exception e) {
            e.printStackTrace();
        }  finally {
            if (channel != null) {
                channel.disconnect();
            }
            if (session != null) {
                session.disconnect();
            }
        }
        return fileNameList;
    }

    /**
     * 下载服务器指定路径的指定文件
     * @param fileName   服务器上的文件名
     * @param downloadPath	要下载的文件在服务器上的路径
     * @param filePath	要存在本地的位置
     * @throws Exception
     * @author wangyijie
     * @data 2017年12月11日
     */
    public static void sftpDownload(String fileName, String downloadPath, String filePath, String host, int port, String user, String password) {
        Session session = null;
        ChannelSftp channel = null;//ChannelSftp类是JSch实现SFTP核心类
        try {
            JSch jsch = new JSch();
            if (port == 0) {
                session = jsch.getSession(user, host);
            } else {
                session = jsch.getSession(user, host, port);
            }
            session.setPassword(password);
            //禁用StrictHostKeyChecking选项会使连接的安全性低于启用该选项的安全性,
            // 因为它可以让您连接到远程服务器而无需验证其SSH主机密钥.如果启用该选项,
            // 则只能连接到SSH客户端已知密钥的服务器
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect(600000);
            channel = (ChannelSftp) session.openChannel("sftp");
            channel.connect(600000);
            if (channel == null) {
                return;
            }
            ChannelSftp sftp = (ChannelSftp) channel;
            //进入服务器指定的文件夹
            sftp.cd(downloadPath);
            //该对象用于查看进度
            sftp.get(fileName, filePath);

        }catch (SftpException e) {
            if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {//2: No such file

                // file doesn't exist
                //throw new RuntimeException(fileName+"文件不存在");
            } else {
                throw new RuntimeException(e);//这个一定要捕捉异常，不然代码报错，为没有返回值
            }
        } catch (Exception e0) {
            throw new RuntimeException(e0);
        } finally {
            if (channel != null) {
                channel.disconnect();
            }
            if (session != null) {
                session.disconnect();
            }
        }
    }


    public static void sftpUpload(String directory,String uploadFile, String host, int port, String user, String password) {
        Session session = null;
        ChannelSftp channel = null;//ChannelSftp类是JSch实现SFTP核心类
        try {
            JSch jsch = new JSch();
            if (port == 0) {
                session = jsch.getSession(user, host);
            } else {
                session = jsch.getSession(user, host, port);
            }
            session.setPassword(password);
            //禁用StrictHostKeyChecking选项会使连接的安全性低于启用该选项的安全性,
            // 因为它可以让您连接到远程服务器而无需验证其SSH主机密钥.如果启用该选项,
            // 则只能连接到SSH客户端已知密钥的服务器
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect(600000);
            channel = (ChannelSftp) session.openChannel("sftp");
            channel.connect(600000);
            if (channel == null) {
                return;
            }
            ChannelSftp sftp = (ChannelSftp) channel;
            //进入服务器指定的文件夹

            try {
                sftp.cd(directory); //进入目录
            } catch (SftpException sException) {
                if (sException.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) { //指定上传路径不存在
                    sftp.mkdir(directory);//创建目录
                    sftp.cd(directory);  //进入目录
                }
            }
            File file = new File(uploadFile);
            InputStream in= new FileInputStream(file);
            sftp.put(in, file.getName());
            in.close();


        } catch (Exception e0) {
            throw new RuntimeException(e0);
        } finally {
            if (channel != null) {
                channel.disconnect();
            }
            if (session != null) {
                session.disconnect();
            }
        }
    }
    public static void main(String args[]) throws UnsupportedEncodingException {
        SFTPUtil.sftpUpload("/home/ruoyi/uploadPath/upload/customerXls","D:\\ruoyi\\E200014210undecode.xls","192.168.200.113",22,"root","11111111");


    }
}
